package com.example.dw.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.example.dw.dto.*;
import com.example.dw.entity.*;
import com.example.dw.mapper.*;
import com.example.dw.service.ExamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考试服务实现类
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@Service
public class ExamServiceImpl implements ExamService {

    @Autowired
    private ExamMapper examMapper;

    @Autowired
    private UserExamMapper userExamMapper;

    @Autowired
    private QuestionBankMapper questionBankMapper;

    @Autowired
    private CourseTypeMapper courseTypeMapper;

    @Override
    @Transactional
    public Map<String, Object> generateExam(Integer userid, ExamGenerateDTO generateDTO) {
        // 检查题目数量是否足够
        Integer totalQuestions = questionBankMapper.getQuestionCountByCourseType(generateDTO.getCourseTypeid());
        Integer requestCount = generateDTO.getQuestionCount() != null ? generateDTO.getQuestionCount() : 10;
        
        if (totalQuestions < requestCount) {
            throw new RuntimeException("题库题目数量不足，当前仅有" + totalQuestions + "道题目");
        }

        // 随机获取题目
        List<QuestionBank> questions = questionBankMapper.getRandomQuestionsByCourseType(
                generateDTO.getCourseTypeid(), requestCount);

        if (questions.isEmpty()) {
            throw new RuntimeException("无法获取题目，请检查题库设置");
        }

        // 创建考试记录
        Exam exam = new Exam();
        exam.setExamName(generateDTO.getExamName() != null ? generateDTO.getExamName() : 
                        "素质测评-" + IdUtil.simpleUUID().substring(0, 8));
        exam.setDescription(generateDTO.getDescription());
        exam.setCreatedBy(userid);
        exam.setCreatedAt(LocalDateTime.now());
        exam.setFullscore(String.valueOf(generateDTO.getFullScore() != null ? generateDTO.getFullScore() : 100));
        exam.setSuccess(String.valueOf(generateDTO.getPassScore() != null ? generateDTO.getPassScore() : 60));
        
        // 设置题目ID列表
        String questionIds = questions.stream()
                .map(q -> String.valueOf(q.getQuestionId()))
                .collect(Collectors.joining(","));
        exam.setQuestionIds(questionIds);

        examMapper.insert(exam);

        // 创建用户考试记录
        UserExam userExam = new UserExam();
        userExam.setUserid(userid);
        userExam.setExamId(exam.getExamId());
        userExam.setCourseTypeid(generateDTO.getCourseTypeid());
        userExam.setStatus(0); // 未完成
        userExam.setCreatedAt(LocalDateTime.now());
        
        userExamMapper.insert(userExam);

        // 返回考试信息和题目
        Map<String, Object> result = new HashMap<>();
        result.put("examId", exam.getExamId());
        result.put("examName", exam.getExamName());
        result.put("description", exam.getDescription());
        result.put("fullScore", exam.getFullscore());
        result.put("passScore", exam.getSuccess());
        result.put("questionCount", questions.size());
        result.put("questions", questions);

        return result;
    }

    @Override
    public Map<String, Object> compareAnswer(Integer userid, AnswerCompareDTO compareDTO) {
        // 获取题目信息
        QuestionBank question = questionBankMapper.getQuestionById(compareDTO.getQuestionId());
        if (question == null) {
            throw new RuntimeException("题目不存在");
        }

        // 比较答案
        boolean correct = Objects.equals(question.getCorrectAnswer(), compareDTO.getAnswer()) ||
                         Objects.equals(question.getAnswer(), compareDTO.getAnswer());

        Map<String, Object> result = new HashMap<>();
        result.put("questionId", compareDTO.getQuestionId());
        result.put("userAnswer", compareDTO.getAnswer());
        result.put("correctAnswer", question.getCorrectAnswer() != null ? question.getCorrectAnswer() : question.getAnswer());
        result.put("correct", correct);
        result.put("explanation", question.getExplanation());
        result.put("score", correct ? (question.getScore() != null ? question.getScore() : 5) : 0);

        return result;
    }

    @Override
    @Transactional
    public Map<String, Object> submitExam(Integer userid, ExamSubmitDTO submitDTO) {
        // 获取考试信息
        Exam exam = examMapper.getExamById(submitDTO.getExamId());
        if (exam == null) {
            throw new RuntimeException("考试不存在");
        }

        // 检查用户是否已经完成该考试
        Integer completed = userExamMapper.checkExamCompleted(userid, submitDTO.getExamId());
        if (completed > 0) {
            throw new RuntimeException("该考试已经完成，不能重复提交");
        }

        // 获取题目列表
        List<String> questionIdStrs = Arrays.asList(exam.getQuestionIds().split(","));
        List<Integer> questionIds = questionIdStrs.stream()
                .map(Integer::valueOf)
                .collect(Collectors.toList());
        
        List<QuestionBank> questions = questionBankMapper.getQuestionsByIds(questionIds);

        // 计算得分
        float totalScore = 0;
        int correctCount = 0;
        List<Map<String, Object>> answerDetails = new ArrayList<>();

        for (QuestionBank question : questions) {
            String userAnswer = submitDTO.getAnswers().get(question.getQuestionId());
            String correctAnswer = question.getCorrectAnswer() != null ? 
                    question.getCorrectAnswer() : question.getAnswer();
            
            boolean correct = Objects.equals(correctAnswer, userAnswer);
            int questionScore = correct ? (question.getScore() != null ? question.getScore() : 5) : 0;
            
            if (correct) {
                correctCount++;
                totalScore += questionScore;
            }

            Map<String, Object> detail = new HashMap<>();
            detail.put("questionId", question.getQuestionId());
            detail.put("questionText", question.getQuestionText());
            detail.put("userAnswer", userAnswer);
            detail.put("correctAnswer", correctAnswer);
            detail.put("correct", correct);
            detail.put("score", questionScore);
            detail.put("explanation", question.getExplanation());
            answerDetails.add(detail);
        }

        // 更新用户考试记录
        userExamMapper.updateExamResult(userid, submitDTO.getExamId(), 1, totalScore);

        // 返回考试结果
        Map<String, Object> result = new HashMap<>();
        result.put("examId", submitDTO.getExamId());
        result.put("totalScore", totalScore);
        result.put("fullScore", Integer.parseInt(exam.getFullscore()));
        result.put("passScore", Integer.parseInt(exam.getSuccess()));
        result.put("passed", totalScore >= Integer.parseInt(exam.getSuccess()));
        result.put("correctCount", correctCount);
        result.put("totalCount", questions.size());
        result.put("accuracy", String.format("%.2f%%", (double) correctCount / questions.size() * 100));
        result.put("answerDetails", answerDetails);

        return result;
    }

    @Override
    public List<UserExam> getAllExams(Integer userid) {
        return userExamMapper.getAllExamsByUser(userid);
    }

    @Override
    public List<UserExam> getUnfinishedExam(Integer userid) {
        return userExamMapper.getUnfinishedExamsByUser(userid);
    }

    @Override
    public Map<String, Object> getExamById(Integer userid, Integer examId) {
        // 获取考试信息
        Exam exam = examMapper.getExamById(examId);
        if (exam == null) {
            throw new RuntimeException("考试不存在");
        }

        // 获取用户考试记录
        UserExam userExam = userExamMapper.getUserExam(userid, examId);

        // 获取题目列表
        List<QuestionBank> questions = new ArrayList<>();
        if (StrUtil.isNotBlank(exam.getQuestionIds())) {
            List<String> questionIdStrs = Arrays.asList(exam.getQuestionIds().split(","));
            List<Integer> questionIds = questionIdStrs.stream()
                    .map(Integer::valueOf)
                    .collect(Collectors.toList());
            questions = questionBankMapper.getQuestionsByIds(questionIds);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("exam", exam);
        result.put("userExam", userExam);
        result.put("questions", questions);

        return result;
    }

    @Override
    public List<Exam> getExamByCourseType(Integer courseTypeid) {
        return examMapper.getExamsByCourseType(courseTypeid);
    }

    @Override
    public Map<String, Object> judgeGenerateExam(Integer userid, ExamGenerateDTO generateDTO) {
        // 检查课程类型是否存在
        CourseType courseType = courseTypeMapper.getCourseTypeById(generateDTO.getCourseTypeid());
        if (courseType == null) {
            throw new RuntimeException("课程类型不存在");
        }

        // 检查题目数量
        Integer totalQuestions = questionBankMapper.getQuestionCountByCourseType(generateDTO.getCourseTypeid());
        Integer requestCount = generateDTO.getQuestionCount() != null ? generateDTO.getQuestionCount() : 10;

        Map<String, Object> result = new HashMap<>();
        result.put("canGenerate", totalQuestions >= requestCount);
        result.put("totalQuestions", totalQuestions);
        result.put("requestCount", requestCount);
        result.put("courseTypeName", courseType.getCourseType());

        if (totalQuestions < requestCount) {
            result.put("message", "题库题目数量不足，当前仅有" + totalQuestions + "道题目，需要" + requestCount + "道");
        } else {
            result.put("message", "可以生成考试");
        }

        return result;
    }

    @Override
    public Map<String, Object> getExamByCourseTypePage(Integer userid, ExamQueryDTO queryDTO) {
        Integer page = queryDTO.getPage() != null && queryDTO.getPage() > 0 ? queryDTO.getPage() : 1;
        Integer size = queryDTO.getSize() != null && queryDTO.getSize() > 0 ? queryDTO.getSize() : 10;
        Integer offset = (page - 1) * size;

        List<UserExam> userExams = userExamMapper.getUserExamsByCourseTypePage(
                userid, queryDTO.getCourseTypeid(), offset, size);
        Integer total = userExamMapper.getUserExamCountByCourseType(userid, queryDTO.getCourseTypeid());

        Map<String, Object> result = new HashMap<>();
        result.put("list", userExams);
        result.put("total", total);
        result.put("page", page);
        result.put("size", size);
        result.put("pages", (total + size - 1) / size);

        return result;
    }

    @Override
    public List<UserExam> getUnfinishedExamByCourseType(Integer userid, Integer courseTypeid) {
        return userExamMapper.getUnfinishedExamsByCourseType(userid, courseTypeid);
    }
} 